﻿using Newtonsoft.Json;
using System.Globalization;
using System.Runtime.Serialization;
using System.Xml;

namespace Gobang.ToolClass
{
    public static class SystemEx
    {
        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static byte[] SerializeBinayr(this object obj)
        {
            byte[] data = null;
            if (obj != null)
            {
                using MemoryStream memoryStream = new MemoryStream();
                DataContractSerializer ser = new DataContractSerializer(typeof(object));
                ser.WriteObject(memoryStream, obj);
                data = memoryStream.ToArray();
            }

            return data;
        }
        public static string SerializeObject<T>(this T t)
        {
            if (t == null)
                return string.Empty;

            return JsonConvert.SerializeObject(t);
        }
        public static T DeserializeObject<T>(this string mes)
        {
            if (string.IsNullOrWhiteSpace(mes))
                return default(T);

            return JsonConvert.DeserializeObject<T>(mes);
        }
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static T Deserialize<T>(byte[] data)
        {
            if (data == null || data.Length == 0)
                return default(T);

            using var memoryStream = new MemoryStream(data);
            using XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(memoryStream, new XmlDictionaryReaderQuotas());
            DataContractSerializer ser = new DataContractSerializer(typeof(T));
            var result = (T)ser.ReadObject(reader, true);
            return result;
        }
        /// <summary>
        /// 转换委托
        /// </summary>
        /// <typeparam name="T">类型参数</typeparam>
        /// <param name="input">入参</param>
        /// <param name="output">返回结果</param>
        /// <returns>返回结果</returns>
        public delegate bool tran<T>(string input, out T output);
        /// <summary>
        /// 转换
        /// </summary>
        /// <typeparam name="T">类型参数</typeparam>
        /// <param name="value"></param>
        /// <param name="defaultv"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static T Convert_Ex<T>(this string value, T defaultv, tran<T> result)
        {
            T output = defaultv;
            if (result(value, out output))
            {
                return output;
            }

            return defaultv;
        }
        /// <summary>
        ///  转换bool
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="defaultv">转换出错默认值</param>
        /// <returns></returns>
        public static bool ToBoolean(this string value, bool defaultv = false)
        {
            return value.Convert_Ex(defaultv, bool.TryParse);
        }

        /// <summary>
        /// 转换byte
        /// </summary>
        /// <param name="value"></param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static byte ToByte(this string value, byte defaultv = 0)
        {
            return value.Convert_Ex(defaultv, byte.TryParse);
        }

        /// <summary>
        /// 转换char
        /// </summary>
        /// <param name="value"></param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static char ToChar(this string value, char defaultv = '0')
        {
            return value.Convert_Ex(defaultv, char.TryParse);
        }
        /// <summary>
        /// 转换datetime
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(this string value)
        {
            return value.ToDateTime(DateTime.MinValue);
        }
        /// <summary>
        /// 转换datetime
        /// </summary>
        /// <param name="value"></param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(this string value, DateTime defaultv)
        {
            return value.Convert_Ex(defaultv, DateTime.TryParse);
        }
        /// <summary>
        /// 时间转换
        /// </summary>
        /// <param name="value">value</param>
        /// <param name="format">格式</param>
        /// <returns></returns>
        public static DateTime ToDateTimeExact(this string value, string format)
        {
            return value.ToDateTimeExact(format, DateTime.Now);
        }
        /// <summary>
        /// 时间转换
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="format">格式</param>
        /// <param name="defaultv">默认值</param>
        /// <returns></returns>
        public static DateTime ToDateTimeExact(this string value, string format, DateTime defaultv)
        {
            return value.ToDateTimeExact(format, CultureInfo.CurrentCulture, DateTimeStyles.None, defaultv);
        }
        /// <summary>
        /// 时间转换
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="format">格式</param>
        /// <param name="cultureInfo">时区信息</param>
        /// <returns></returns>
        public static DateTime ToDateTimeExact(this string value, string format, CultureInfo cultureInfo)
        {
            return value.ToDateTimeExact(format, cultureInfo, DateTime.Now);
        }
        /// <summary>
        /// 时间转换
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="format">格式</param>
        /// <param name="cultureInfo">默认值</param>
        /// <param name="defaultv">时区信息</param>
        /// <returns></returns>
        public static DateTime ToDateTimeExact(this string value, string format, CultureInfo cultureInfo, DateTime defaultv)
        {
            return value.ToDateTimeExact(format, cultureInfo, DateTimeStyles.None, defaultv);
        }
        /// <summary>
        /// 时间转换DateTime
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="format">格式</param>
        /// <param name="cultureInfo">默认值</param>
        /// <param name="dateTimeStyles">时区信息</param>
        /// <param name="defaultv">时间格式样式</param>
        /// <returns></returns>
        public static DateTime ToDateTimeExact(this string value, string format, CultureInfo cultureInfo, DateTimeStyles dateTimeStyles, DateTime defaultv)
        {
            DateTime result;
            if (DateTime.TryParseExact(value, format, cultureInfo, dateTimeStyles, out result))
            {
                return result;
            }

            return defaultv;
        }
        /// <summary>
        /// 转换TimeSpan
        /// </summary>
        /// <param name="value">参数</param>
        /// <returns></returns>
        public static TimeSpan ToTimeSpan(this string value)
        {
            return value.ToTimeSpan(TimeSpan.Zero);
        }
        /// <summary>
        /// 转换TimeSpan
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="defaultv">转换失败默认值</param>
        /// <returns></returns>
        public static TimeSpan ToTimeSpan(this string value, TimeSpan defaultv)
        {
            return value.Convert_Ex(defaultv, TimeSpan.TryParse);
        }
        /// <summary>
        /// 转换decimal
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static decimal ToDecimal(this string value, decimal defaultv = 0m)
        {
            return value.Convert_Ex(defaultv, decimal.TryParse);
        }
        /// <summary>
        /// 转换double
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static double ToDouble(this string value, double defaultv = 0.0)
        {
            return value.Convert_Ex(defaultv, double.TryParse);
        }
        /// <summary>
        /// 转换short
        /// </summary>
        /// <param name="value">value</param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static short ToInt16(this string value, short defaultv = 0)
        {
            return value.Convert_Ex(defaultv, short.TryParse);
        }
        /// <summary>
        ///  转换int
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static int ToInt32(this string value, int defaultv = 0)
        {
            return value.Convert_Ex(defaultv, int.TryParse);
        }
        /// <summary>
        /// 转换long
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static long ToInt64(this string value, long defaultv = 0L)
        {
            return value.Convert_Ex(defaultv, long.TryParse);
        }
        /// <summary>
        /// 转换sbyte
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static sbyte ToSByte(this string value, sbyte defaultv = 0)
        {
            return value.Convert_Ex(defaultv, sbyte.TryParse);
        }
        /// <summary>
        /// 转换float
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static float ToSingle(this string value, float defaultv = 0f)
        {
            return value.Convert_Ex(defaultv, float.TryParse);
        }
        /// <summary>
        /// 转换ushort
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static ushort ToUInt16(this string value, ushort defaultv = 0)
        {
            return value.Convert_Ex(defaultv, ushort.TryParse);
        }
        /// <summary>
        /// 转换uint
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static uint ToUInt32(this string value, uint defaultv = 0u)
        {
            return value.Convert_Ex(defaultv, uint.TryParse);
        }
        /// <summary>
        /// 转换ulong
        /// </summary>
        /// <param name="value">参数</param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static ulong ToUInt64(this string value, ulong defaultv = 0uL)
        {
            return value.Convert_Ex(defaultv, ulong.TryParse);
        }
        /// <summary>
        /// 转换float
        /// </summary>
        /// <param name="value"></param>
        /// <param name="defaultv"></param>
        /// <returns></returns>
        public static float ToFloat(this string value, float defaultv = 0f)
        {
            return value.Convert_Ex(defaultv, float.TryParse);
        }
        /// <summary>
        /// bool转short
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static short BooleanToShort(this bool value)
        {
            return value ? (short)1 : (short)0;
        }
        /// <summary>
        /// short转bool
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool ShortToBoolean(this short value)
        {
            return value == 1;
        }
    }
}
